﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Excel;
using Zzva.Report;
using System.Reflection;
using Zzva.Common;



namespace Zzva.ReportExcel
{
    public class TOneTableExcel
    {


       

        private int mvarColumnBegin; //начало точки сканипрвания первого этапа таблицы
        private int mvarRowBegin;
        private int mvarColumnBeginCur;//начало точки сканирования очередного этапа таблицы
        private int mvarRowBeginCur;
        private TReportFieldEntity mvarReportFieldEntity;
        private Excel.Worksheet mvarSheet;

        private int mvarTitleColumn;
        private int mvarTitleRow;


        public TOneTableExcel(Excel.Worksheet pSheet, TReportFieldEntity pReportFieldEntity)
        {
            try
            {

                mvarTitleColumn = 1;
                mvarTitleRow = 2;



                mvarColumnBegin = 1;
                mvarRowBegin = 3;
                mvarColumnBeginCur = mvarColumnBegin;
                mvarRowBeginCur = mvarRowBegin;
                mvarReportFieldEntity = pReportFieldEntity;
                mvarSheet = pSheet;
                DrawFrame(mvarSheet, mvarReportFieldEntity);

            }

            catch (Exception e1) { throw e1; }
            finally { }
        }


        public string Title
        {
            set
            {
                string lTitle = value;
                Range lRange;
                lRange = (Range)mvarSheet.Cells[mvarTitleRow, mvarTitleColumn];
                lRange.Formula = lTitle;
            }
        }




        private void DrawFrame(Excel.Worksheet pSht, TReportFieldEntity pReportFieldEntity)
        {
            try
            {

                int lColumnBegin = mvarColumnBegin;
                int lRowBegin = mvarRowBegin;
                TCell lCellEnd;
                int lColumnEnd;
                int lRowEnd;
                int lColumnCur;
                int lRowCur;


                //lCellEnd = DrawTitleTable(pSht, pReportFieldEntity, lColumnBegin, lRowBegin);
                lCellEnd = DrawTitleTableMen(pSht, pReportFieldEntity, lColumnBegin, lRowBegin);


                //пробежимся проставим номера столбцов
                int lNumCur = 0;
                Range lRngCur;
                lRowCur = lCellEnd.Row + 1;
                lRowEnd = lRowCur;
                lColumnCur = lColumnBegin;
                lColumnEnd = lCellEnd.Column;
                for (int i = lColumnCur; i <= lColumnEnd; i++)
                {
                    lNumCur = lNumCur + 1;
                    lRngCur = (Range)pSht.Cells[lRowCur, i];
                    lRngCur.Formula = lNumCur;
                    lRngCur.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                    lRngCur.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
                }






                //сетку и фон шапки заголовков

                ////lRngCur = pSht.get_Range(pSht.Cells[lRowBegin, lColumnBegin],
                ////                      pSht.Cells[lRowEnd, lColumnEnd]);
                lRngCur = pSht.get_Range(pSht.Cells[lRowBegin + 1, lColumnBegin],
                                      pSht.Cells[lRowEnd, lColumnEnd]); //не рисуем на корневом "Report"

                lRngCur.Borders[XlBordersIndex.xlEdgeBottom].LineStyle = XlLineStyle.xlContinuous;
                lRngCur.Borders[XlBordersIndex.xlEdgeLeft].LineStyle = XlLineStyle.xlContinuous;
                lRngCur.Borders[XlBordersIndex.xlEdgeRight].LineStyle = XlLineStyle.xlContinuous;
                lRngCur.Borders[XlBordersIndex.xlEdgeTop].LineStyle = XlLineStyle.xlContinuous;
                lRngCur.Borders[XlBordersIndex.xlInsideHorizontal].LineStyle = XlLineStyle.xlContinuous;
                lRngCur.Borders[XlBordersIndex.xlInsideVertical].LineStyle = XlLineStyle.xlContinuous;
                lRngCur.Interior.ColorIndex = 15;


                mvarColumnBeginCur = mvarColumnBegin;
                mvarRowBeginCur = lRowEnd + 1;



            }

            catch (Exception e1) { throw e1; }
            finally { }
        }


        //Возвращает последнюю ячейку после прорисовки
        private TCell DrawTitleTableMen(Excel.Worksheet pSht, TReportFieldEntity pReportFieldEntity,
                                  int pColumnBegin, int pRowBegin)
        {
            try
            {
                int lColFieldValue;
                int lColLevel;
                Range lRng;
                TReportListField lReportListField;
                TReportFieldValue lReportFieldValue;
                TReportFieldEntity lReportFieldEntity;
                int lColumnCur;
                int lRowCur;
                int lDeltaRow;
                int lDeltaColumn;
                int lColumnEnd;
                int lRowEnd;
                TCell lCellEnd;
                TCell lCellEndChild;
                lColumnCur = pColumnBegin;
                lRowCur = pRowBegin;


                lColLevel = pReportFieldEntity.GetColLevel();
                lDeltaRow = lColLevel - 1;
                lRowEnd = pRowBegin + lDeltaRow + 1;

                lColFieldValue = pReportFieldEntity.GetColFieldValue();
                lDeltaColumn = lColFieldValue - 1;
                lColumnEnd = pColumnBegin + lDeltaColumn;

                lCellEnd = new TCell() { Row = lRowEnd, Column = lColumnEnd };



                lRng = pSht.get_Range(pSht.Cells[lRowCur, lColumnCur],
                                      pSht.Cells[lRowCur, lColumnCur + lDeltaColumn]);
                
                
                
                //Не показываем название виртуального корневого объекта "Report"
                ////lRng.MergeCells = true;
                ////lRng.Formula = pReportFieldEntity.Naim;
                ////lRng.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                ////lRng.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;





                lRowCur = lRowCur + 1;




                lReportListField = pReportFieldEntity.ReportListField;
                foreach (TReportFieldBase lReportField in lReportListField)
                {

                    if (lReportField is TReportFieldValue)
                    {
                        lReportFieldValue = (TReportFieldValue)lReportField;


                        lRng = pSht.get_Range(pSht.Cells[lRowCur, lColumnCur],
                                              pSht.Cells[lRowCur + lDeltaRow, lColumnCur]);




                        
                        lRng.MergeCells = true;
                        lRng.Formula = lReportFieldValue.Naim;
                        lRng.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                        lRng.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;
                        lRng.ColumnWidth = lReportFieldValue.ColumnWidth;







                        lReportFieldValue.NumberInTraversal = lColumnCur;


                        lColumnCur = lColumnCur + 1;

                    }
                    else if (lReportField is TReportFieldEntity)
                    {
                        lReportFieldEntity = (TReportFieldEntity)lReportField;
                        lCellEndChild = DrawTitleTable(pSht, lReportFieldEntity, lColumnCur, lRowCur, lColumnEnd, lRowEnd);


                        //lColumnCur = lColumnCur + lReportFieldEntity.GetColFieldValue();
                        lColumnCur = lCellEndChild.Column + 1;

                    }
                    else { throw (new CommonException("Нет такого класса")); }

                }

                return lCellEnd;
            }
            catch (Exception e1) { throw e1; }
            finally { }
        }































        public void SetValue(string pOboznFull, object pValueField)
        {
            try
            {

                TReportFieldValue lReportFieldValue;
                TReportFieldBase lReportFieldBase;

                lReportFieldBase = mvarReportFieldEntity.GetField(pOboznFull);

                if (lReportFieldBase is TReportFieldValue){lReportFieldValue = (TReportFieldValue)lReportFieldBase;}
                else{throw (new CommonException("Это не объект TReportFieldValue")); }

                Range lRange;

                ////lRange = mvarSheet.get_Range(mvarSheet.Cells[lRowBegin, lColumnBegin],
                ////      mvarSheet.Cells[lRowEnd, lColumnEnd]);

                lRange = (Range)mvarSheet.Cells[mvarRowBeginCur, lReportFieldValue.NumberInTraversal];

                ////lRange.NumberFormat = lReportFieldValue.NumberFormat;
                lRange.Font.Size = lReportFieldValue.FontSize;
                lRange.Formula = pValueField;

             
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }





        public void NewLine()
        {
            try
            {
                mvarRowBeginCur = mvarRowBeginCur + 1;
            }

            catch (Exception e1) { throw e1; }
            finally { }
        }





 






        private class TCell
        {
            public int Row { get; set;}
            public int Column { get; set; }
        }



        
 












        //Возвращает последнюю ячейку после прорисовки
        private TCell DrawTitleTable(Excel.Worksheet pSht, TReportFieldEntity pReportFieldEntity,
                                  int pColumnBegin, int pRowBegin,
                                  int pColumnMax,int pRowMax)
        {
            try
            {


                int lColFieldValue;
                int lColLevel;
                Range lRng;
                TReportListField lReportListField;
                TReportFieldValue lReportFieldValue;
                TReportFieldEntity lReportFieldEntity;
                int lColumnCur;
                int lRowCur;
                
                
                int lDeltaRow;
                int lDeltaColumn;

                int lColumnEnd;
                int lRowEnd;
                TCell lCellEnd;


                TCell lCellEndChild;



                lColumnCur = pColumnBegin;
                lRowCur = pRowBegin;

           

                lColLevel = pReportFieldEntity.GetColLevel();
                lDeltaRow = lColLevel - 1;
                lRowEnd = pRowBegin + lDeltaRow +1;

                lColFieldValue = pReportFieldEntity.GetColFieldValue();
                lDeltaColumn = lColFieldValue - 1;
                lColumnEnd = pColumnBegin + lDeltaColumn;


                lCellEnd = new TCell() { Row = lRowEnd, Column = lColumnEnd };






 ////           lRng = pSht.get_Range(pSht.Cells[pRowCur, pColumnCur],
 ////                                 pSht.Cells[pRowCur, pColumnCur + lColFieldValue -1]);
                lRng = pSht.get_Range(pSht.Cells[lRowCur, lColumnCur],
                                      pSht.Cells[lRowCur, lColumnCur + lDeltaColumn]);






                lRng.MergeCells = true;
                lRng.Formula = pReportFieldEntity.Naim;
                lRng.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                lRng.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;






                lRowCur = lRowCur + 1;




                lReportListField = pReportFieldEntity.ReportListField;
                foreach (TReportFieldBase lReportField in lReportListField)
                {

                    if (lReportField is TReportFieldValue)
                    {
                        lReportFieldValue = (TReportFieldValue)lReportField;

                 



////                        lRng = pSht.get_Range(pSht.Cells[lRowCur, lColumnCur],
////                                              pSht.Cells[lRowCur + lDeltaRow, lColumnCur]);

                        lRng = pSht.get_Range(pSht.Cells[lRowCur, lColumnCur],
                                              pSht.Cells[pRowMax, lColumnCur]);






                        lRng.MergeCells = true;
                        lRng.Formula = lReportFieldValue.Naim;
                        lRng.HorizontalAlignment = Excel.XlHAlign.xlHAlignCenter;
                        lRng.VerticalAlignment = Excel.XlVAlign.xlVAlignCenter;



                        lReportFieldValue.NumberInTraversal = lColumnCur;


                        lColumnCur = lColumnCur + 1;




                    }
                    else if (lReportField is TReportFieldEntity)
                    {
                        lReportFieldEntity = (TReportFieldEntity)lReportField;

                        ////DrawTitleTable(pSht, lReportFieldEntity, lColumnCur, lRowCur);
                        lCellEndChild = DrawTitleTable(pSht, lReportFieldEntity, lColumnCur, lRowCur,pColumnMax,pRowMax);

                        ////lColumnCur = lColumnCur + lReportFieldEntity.GetColFieldValue();
                        lColumnCur = lCellEndChild.Column + 1;


                    }
                    else{throw (new CommonException("Нет такого класса"));}

                }


                return lCellEnd; 

            }
            catch (Exception e1) { throw e1; }
            finally { }
        }





    }
}
